package com.fishery.customization.service.impl;

import com.fishery.customization.entity.ConstantValue;
import com.fishery.customization.entity.FunctionLabel;
import com.fishery.customization.entity.OneLevelLabel;
import com.fishery.customization.service.FunctionLabelService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

@Service
public class FunctionLabelServiceImpl implements FunctionLabelService {

	@Autowired
	private RedisTemplate redisTemplate;

	@Override
	public boolean saveFunctionLabel(String functionName, OneLevelLabel label) {
		redisTemplate.opsForHash().put(ConstantValue.REDIS_FUNCTION_LABEL, functionName, label);
		return true;
	}

	@Override
	public boolean updateFunctionLabel(String oldFunctionName, String newFunctionName, OneLevelLabel label) {
		if (StringUtils.isEmpty(newFunctionName)) {
			// 权限名不需要修改，需要修改标签，直接替换entry的value
			redisTemplate.opsForHash().put(ConstantValue.REDIS_FUNCTION_LABEL, oldFunctionName, label);
		} else {
			// 权限名需要修改
			if (label == null || label.getChildren().isEmpty()) {
				// 不需要修改标签内容，因此需要获取值先
				Object val = redisTemplate.opsForHash().get(ConstantValue.REDIS_FUNCTION_LABEL, oldFunctionName);
				// 修改的是权限名，需要把原先的权限名对应的entry删除
				redisTemplate.opsForHash().delete(ConstantValue.REDIS_FUNCTION_LABEL, oldFunctionName);
				// 保存新的权限标签
				redisTemplate.opsForHash().put(ConstantValue.REDIS_FUNCTION_LABEL, newFunctionName, val);
			} else {
				// 权限名需要修改
				redisTemplate.opsForHash().delete(ConstantValue.REDIS_FUNCTION_LABEL, oldFunctionName);
				redisTemplate.opsForHash().put(ConstantValue.REDIS_FUNCTION_LABEL, newFunctionName, label);
			}
		}
		return true;
	}

	@Override
	public boolean removeFunctionLabel(String functionName) {
		redisTemplate.opsForHash().delete(ConstantValue.REDIS_FUNCTION_LABEL, functionName);
		return true;
	}

	@Override
	public List<FunctionLabel> getAllFunctionLabels() {
		Set keys = redisTemplate.opsForHash().keys(ConstantValue.REDIS_FUNCTION_LABEL);
		List<FunctionLabel> functionLabels = new ArrayList<>(keys.size());
		keys.forEach(key -> {
			functionLabels.add(new FunctionLabel((String) key,
					(OneLevelLabel) redisTemplate.opsForHash().get(ConstantValue.REDIS_FUNCTION_LABEL, key)));
		});
		return redisTemplate.opsForHash().values(ConstantValue.REDIS_FUNCTION_LABEL);
	}

	@Override
	public OneLevelLabel getOneLevelLabelByFunctionName(String functionName) {
		return (OneLevelLabel) redisTemplate.opsForHash().get(ConstantValue.REDIS_FUNCTION_LABEL, functionName);
	}

	@Override
	public List<OneLevelLabel> getOneLevelLabelsByFunctionNames(List<String> functionNames) {
		// 通过权限名映射到一级标签,并做去重处理
		Map<String, OneLevelLabel> labelMap = new HashMap<>(4);
		functionNames.forEach(functionName -> {
			OneLevelLabel oneLevelLabel = getOneLevelLabelByFunctionName(functionName);
			OneLevelLabel oneLevelLabelInMap = labelMap.get(oneLevelLabel.getName());
			if (oneLevelLabelInMap != null) {
				oneLevelLabelInMap.getChildren().addAll(oneLevelLabel.getChildren());
			} else {
				labelMap.put(oneLevelLabel.getName(), oneLevelLabel);
			}
		});
		return new ArrayList<>(labelMap.values());
	}

	@Override
	public List<OneLevelLabel> getAllOneLevelLabels() {
		// 通过权限名映射到一级标签,并做去重处理
		Map<String, OneLevelLabel> labelMap = new HashMap<>(4);
		List<OneLevelLabel> oneLevelLabels = redisTemplate.opsForHash()
				.values(ConstantValue.REDIS_FUNCTION_LABEL);
		oneLevelLabels.forEach(oneLevelLabel -> {
			OneLevelLabel oneLevelLabelInMap = labelMap.get(oneLevelLabel.getName());
			if (oneLevelLabelInMap != null) {
				oneLevelLabelInMap.getChildren().addAll(oneLevelLabel.getChildren());
			} else {
				labelMap.put(oneLevelLabel.getName(), oneLevelLabel);
			}
		});
		return new ArrayList<>(labelMap.values());
	}
}
